﻿using Common;
using System;
using System.Timers;

namespace TaskApp
{
    /**
        部署到 linux 下，需要首先删除 所有工程项目目录下 bin、obj 文件夹，然后在 要切换到 启动执行的项目文件夹下，运行 dotnet run ，
        这时候所有工程项目下，会生成 obj、bin 文件夹。

        部署发布方式：
                dotnet 命令发布
                VS 手工发布 => 运行程序

        生产环境下使用Release版本：dotnet run -c Release

        更多情况下，推荐 publish => 
                        dotnet publish -o  /data/output -c Release 
                        dotnet publish csharp/TaskApp -o csharp_publish/TaskApp -c Release

        运行发布后的程序：dotnet csharp_publish/TaskApp/TaskApp.dll


        修改代码后清理编印： 
                    dotnet clean
                    dotnet clean -c Release

       部署方式：

        1. nohup dotnet xxx.dll &
            
            生成的 nuhup.out 文件 来自于 Console.WriteLine。

            注意：需用 exit 来结束当前的terminal。。。。否则这个后台进程会退出。。。

        2. supervisord 进程管理工具。。。 （微软推荐）

        安装： yum -y install supervisor 卸载： yum -y remove supervisor

        supervisorctl status all

        service  supervisord start  或 systemctl start supervisord.service

        ps -ef | grep supervisord   

        cd /etc

        ls | grep super

        编写服务配置：

            [program:TaskApp]
            directory=/usr/local/projects/csharp_publish/TaskApp  # 程序所在的根目录
            command=/usr/bin/dotnet /usr/local/projects/csharp_publish/TaskApp/TaskApp.dll # 绝对路径，程序要运行的 文件
            autostart=true  # 是否自动启动
            autorestart=true # 如果程序挂掉，是否重新启动 
            stdout_logfile=/usr/local/projects/csharp_publish/TaskApp/logs/out.log  # 日志输出地
            stderr_logfile=/usr/local/projects/csharp_publish/TaskApp/logs/err.log  # 错误输出地


        将 程序的配置文件 放到 supervisord.d 目录

         mv /usr/local/projects/csharp/TaskApp/TaskApp.ini /etc/supervisord.d/

        stdout_logfile 与  stderr_logfile 设置了日志目录，所以需要手动创建 logs 文件夹

        若报：

            '\xef\xbb\xbf[program:TaskApp]\r\n'

            把TaskApp.ini文件另存为ASCII编码文件就可以了。

        service  supervisord restart

        supervisorctl status all  所有 supervisord 守护的进程

        查看所有跟 dotnet 有关的进程
            ps -aux | grep dotnet 
                或
            ps -ef | grep dotnet 

        ----------------------------------------------------------------------------------------------------------------------------
        使用nssm 部署成 windows 服务：
            http://www.nssm.cc/download
            http://www.nssm.cc/commands

           1. 下载 nssm ，控制台下执行 nssm install service_name
           2. 
                Application Path 填写 dotnet  如：C:\Program Files (x86)\dotnet\dotnet.exe
                Startup Direcotry 填写 程序根目录
                Arguments 填写要 运行的 带扩展名的文件名
           3. 点击 install service 

        部署模式：
            框架依赖
            独立 (体积大)

     * 
     */
    class Program
    {

        //static void Main(string[] args)
        //{
        //    var tokenSource = new CancellationTokenSource();

        //    Task.Factory.StartNew(() =>
        //    {
        //        while (!tokenSource.IsCancellationRequested)
        //        {
        //            Console.WriteLine($"{DateTime.Now} :业务逻辑处理中");
        //            System.Threading.Thread.Sleep(1000);
        //        }
        //    }).ContinueWith(t =>
        //    {
        //        Console.WriteLine("服务安全退出！");
        //        Environment.Exit(0);  //强制退出
        //    });

        //    Console.WriteLine("服务成功开启!");

        //   全局统一配置可以使用 apollo ： https://github.com/ctripcorp/apollo
        //    while (!"Y".Equals(ConfigurationManager.Configuration["isquit"], StringComparison.OrdinalIgnoreCase))
        //        Thread.Sleep(1000);

        //    tokenSource.Cancel();
        //}

        static void Main(string[] args)
        {
            Timer timer = new Timer();
            timer.Interval = 1000;
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
            //Console.ReadKey();  如果要发布成 后台服务/守护进程，不能使用 Console.ReadKey

            //让程序不自动退出
            while (true)
            {
                System.Threading.Thread.Sleep(1000);
            }
        }

        private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            Util.Exec();
        }
    }
}
